package com.lcz.authority.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lcz.authority.admin.mapper.SysResourceMapper;
import com.lcz.authority.admin.mapper.SysRoleResourceMapper;
import com.lcz.authority.admin.service.SysResourceService;
import com.lcz.authority.common.constant.Constants;
import com.lcz.authority.common.core.mybatis.MPJLambdaWrapperX;
import com.lcz.authority.common.core.page.PageResult;
import com.lcz.authority.common.domain.TreeSelect;
import com.lcz.authority.common.domain.entity.SysResourceEntity;
import com.lcz.authority.common.domain.entity.SysRoleEntity;
import com.lcz.authority.common.domain.entity.SysRoleResourceEntity;
import com.lcz.authority.common.domain.entity.SysUserEntity;
import com.lcz.authority.common.domain.model.SysRoleAuth;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lcz
 * @desc 资源服务impl
 * @mail lcz_0130@163.com
 * @date 2024/05/06
 */

@Service
public class SysResourceServiceImpl extends ServiceImpl<SysResourceMapper, SysResourceEntity> implements SysResourceService {

    @Resource
    private SysResourceMapper resourceMapper;
    @Resource
    private SysRoleResourceMapper roleResourceMapper;

    @Override
    public PageResult<SysResourceEntity> page(SysResourceEntity sysResourceEntity) {
        return resourceMapper.selectPage(sysResourceEntity);
    }

    /**
     * 新增接口资源信息
     *
     * @param resource
     * @return
     */
    @Override
    public int insertResource(SysResourceEntity resource) {

        int row = resourceMapper.insert(resource);
        return row;
    }

    /**
     * 清空 sys_resource 数据库
     */
    @Override
    public void truncateResource() {
        resourceMapper.truncateResource();
    }

    /**
     * 根据角色ID查询资源编码列表
     *
     * @param roleId 角色ID
     * @return 权限列表
     */
    @Override
    public Set<String> selectResourceCodeByRoleId(String roleId) {
        //        select sr.resource_code
        //        from sys_role_resource sr
        //                 left join sys_role r on r.role_id = sr.role_id
        //        where sr.role_id = #{roleId}
        //          AND r.status = 0
        MPJLambdaWrapperX<SysResourceEntity> wrapperX = new MPJLambdaWrapperX<>();
        wrapperX.select(SysResourceEntity::getResourceCode);
        wrapperX.eq(SysRoleResourceEntity::getRoleId, roleId);
        wrapperX.eq(SysRoleEntity::getStatus, SysRoleEntity.IsStatus.NO);
        wrapperX.leftJoin(SysRoleEntity.class, "sys_role", SysRoleEntity::getRoleId, SysRoleResourceEntity::getRoleId);
        List<SysRoleResourceEntity> sysRoleResourceEntities = resourceMapper.selectJoinList(SysRoleResourceEntity.class, wrapperX);
        return sysRoleResourceEntities.stream().map(SysRoleResourceEntity::getResourceCode).collect(Collectors.toSet());
    }

    @Override
    public List<SysResourceEntity> selectApiResourceList(String userId) {
        SysResourceEntity resourceEntity = new SysResourceEntity();
        resourceEntity.setRequiredPermissionFlag(Constants.YES);
        return selectApiResourceList(resourceEntity, userId);
    }

    @Override
    public List<SysRoleAuth> selectSysRoleAuthAll() {
        return roleResourceMapper.selectList().stream()
                .map(SysRoleAuth::new).collect(Collectors.toList());
    }

    @Override
    public List<SysResourceEntity> selectApiResourceList(SysResourceEntity resource, String userId) {
        List<SysResourceEntity> resourceList;
        // 管理员显示所有资源信息
        if (SysUserEntity.isAdmin(userId)) {
            resourceList = resourceMapper.selectResourceList(resource);
        } else {
            resource.getParams().put("userId", userId);
            resourceList = resourceMapper.selectResourceListByUserId(resource);
        }
        return resourceList;
    }

    @Override
    public List<String> selectResourceListByRoleId(String roleId) {
        //        select r.resource_id
        //        from sys_resource r
        //                 left join sys_role_resource rr on r.resource_code = rr.resource_code
        //        where rr.role_id = #{roleId}
        MPJLambdaWrapperX<SysResourceEntity> wrapperX = new MPJLambdaWrapperX<>();
        wrapperX.select(SysResourceEntity::getResourceId);
        wrapperX.eq(SysRoleResourceEntity::getRoleId, roleId);
        wrapperX.leftJoin(SysRoleResourceEntity.class, SysRoleResourceEntity::getResourceCode, SysResourceEntity::getResourceCode);
        return resourceMapper.selectJoinList(SysResourceEntity.class, wrapperX).stream().map(SysResourceEntity::getResourceId).collect(Collectors.toList());
//        return resourceMapper.selectResourceListByRoleId(roleId);
    }

    @Override
    public List<TreeSelect> buildResourceTreeSelect(List<SysResourceEntity> resources) {

        List<TreeSelect> treeSelects = new ArrayList<>();

        Map<String, List<SysResourceEntity>> map = resources.stream().collect(
                Collectors.groupingBy(SysResourceEntity::getClassName));
        long size = 0L;
        for (String key : map.keySet()) {
            String modularName = map.get(key).get(0).getModularName();
            TreeSelect treeSelect = new TreeSelect(UUID.randomUUID().toString().replace("-", ""), modularName, map.get(key));
            treeSelects.add(treeSelect);
        }
        return treeSelects;
    }

    @Override
    public void editRoleResource(String roleId, String[] resourceIds) {
        // 删除角色与api资源关联
        roleResourceMapper.delete(new QueryWrapper<SysRoleResourceEntity>().eq("role_id", roleId));
        //添加角色与api资源管理
        if (resourceIds.length > 0) {
            List<SysResourceEntity> resourceEntities = resourceMapper.selectBatchIds(Arrays.asList(resourceIds));
            insertRoleMenu(roleId, resourceEntities);
        }
    }

    public void insertRoleMenu(String roleId, List<SysResourceEntity> resourceEntities) {
        List<SysRoleResourceEntity> rrList = new ArrayList<>();
        for (SysResourceEntity resourceEntity : resourceEntities) {
            SysRoleResourceEntity rr = new SysRoleResourceEntity();
            rr.setRoleId(roleId);
            rr.setResourceCode(resourceEntity.getResourceCode());
            rrList.add(rr);
        }
        //批量保存角色与资源关系
        roleResourceMapper.insertBatchLarge(rrList);

    }

}
